{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6f27387ddb18525a",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "学习目标\n",
    "- 知道数组与数之间的运算\n",
    "- 知道数组与数组之间的运算\n",
    "- 说明数组间运算的广播机制"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9531936f48a497f5",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "# 1 数组与数的运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "73cf7e47e7ef44d0",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-20T11:18:03.190970200Z",
     "start_time": "2024-02-20T11:18:03.149533700Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[2, 3, 4, 3, 2, 5],\n",
       "       [6, 7, 2, 3, 4, 2]])"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "arr = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])\n",
    "arr + 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "424a5d78f468c10c",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-20T11:18:03.212470800Z",
     "start_time": "2024-02-20T11:18:03.194938100Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.5, 1. , 1.5, 1. , 0.5, 2. ],\n",
       "       [2.5, 3. , 0.5, 1. , 1.5, 0.5]])"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr / 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "4aea3ad3bf941421",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-20T11:18:03.225109700Z",
     "start_time": "2024-02-20T11:18:03.214472200Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "# 可以对比python列表的运算，看出区别\n",
    "a = [1, 2, 3, 4, 5]\n",
    "a * 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "89716eefbfa552d5",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-20T11:18:03.228468200Z",
     "start_time": "2024-02-20T11:18:03.221024200Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 3,  6,  9,  6,  3, 12],\n",
       "       [15, 18,  3,  6,  9,  3]])"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr * 3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "561b8c3bcca9faea",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "# 2 数组与数组的运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "e5fb595fa031f3b3",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-20T11:18:03.260591100Z",
     "start_time": "2024-02-20T11:18:03.229468200Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "arr1 = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])\n",
    "arr2 = np.array([[1, 2, 3, 4], [3, 4, 5, 6]])\n",
    "# arr1 + arr2 # 不能运行"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2317ec26c5e4dd34",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "## 2.1 广播机制\n",
    "数组在进行矢量化运算时，要求数组的形状是相等的。当形状不相等的数组执行算术运算的时候，就会出现广播机制，该机制会对数组进行扩展，使数组的shape属性值一样，这样，就可以进行矢量化运算了。下面通过一个例子进行说明："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "b4b8b5de5f3ede8b",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-20T11:18:03.261591400Z",
     "start_time": "2024-02-20T11:18:03.236421700Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4, 1)"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr1 = np.array([[0],[1],[2],[3]])\n",
    "arr1.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "3adfe704ea1a60b4",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-20T11:18:03.261591400Z",
     "start_time": "2024-02-20T11:18:03.243065200Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0],\n",
       "       [1],\n",
       "       [2],\n",
       "       [3]])"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "e40b488116e35f16",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-20T11:18:03.262626500Z",
     "start_time": "2024-02-20T11:18:03.249897600Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3,)"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr2 = np.array([1,2,3])\n",
    "arr2.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "3856a55ecadbc577",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-20T11:18:03.262626500Z",
     "start_time": "2024-02-20T11:18:03.255514400Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2, 3],\n",
       "       [2, 3, 4],\n",
       "       [3, 4, 5],\n",
       "       [4, 5, 6]])"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr1+arr2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f5a96baf68e51d7",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "上述代码中，数组arr1是4行1列，arr2是1行3列。这两个数组要进行相加，按照广播机制会对数组arr1和arr2都进行扩展，使得数组arr1和arr2都变成4行3列。\n",
    "\n",
    "下面通过一张图来描述广播机制扩展数组的过程：\n",
    "\n",
    "![](../.images/image-20190620005224076.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aecc95d1c5a4defb",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "这句话乃是理解广播的核心。广播主要发生在两种情况，一种是两个数组的维数不相等，但是它们的后缘维度的轴长相符，另外一种是有一方的长度为1。\n",
    "\n",
    "广播机制实现了时两个或两个以上数组的运算，即使这些数组的shape不是完全相同的，只需要满足如下任意一个条件即可。\n",
    "\n",
    "- 如果两个数组的后缘维度（trailing dimension，即从末尾开始算起的维度）的轴长度相符，\n",
    "- 或其中的一方的长度为1。\n",
    "广播会在缺失和（或）长度为1的维度上进行。\n",
    "广播机制需要扩展维度小的数组，使得它与维度最大的数组的shape值相同，以便使用元素级函数或者运算符进行运算。\n",
    "如果是下面这样，则不匹配：\n",
    "    ```\n",
    "    A  (1d array): 10\n",
    "    B  (1d array): 12\n",
    "    A  (2d array):      2 x 1\n",
    "    B  (3d array):  8 x 4 x 3\n",
    "    ```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a53185d6f33808",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "# 3 小结\n",
    "- 数组运算,满足广播机制,就OK【知道】\n",
    "    - 1.维度相等\n",
    "    - 2.shape(其中对应的地方为1,也是可以的)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
